package queue2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MessageQueue {
    private static final int CAPACITY = 10;
    private String[] messageQueue = new String[CAPACITY];
    private int head = 0;
    private int tail = 0;

    private final Lock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();

    public void put(String message) throws InterruptedException {
        lock.lock();
        try {
            while ((tail + 1) % CAPACITY == head) {
                notFull.await();
            }
            messageQueue[tail] = message;
            tail = (tail + 1) % CAPACITY;
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    public String take() throws InterruptedException {
        lock.lock();
        try {
            while (head == tail) {
                notEmpty.await();
            }
            String message = messageQueue[head];
            head = (head + 1) % CAPACITY;
            notFull.signal();
            return message;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        MessageQueue messageQueue = new MessageQueue();
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                String message = "message " + i;
                try {
                    messageQueue.put(message);
                    System.out.println("Produced message: " + message);
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    String message = messageQueue.take();
                    System.out.println("Consumed message: " + message);
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        producer.start();
        consumer.start();
    }
}
